/*** Ogre::Root is a very convenient facade class ***/

module dogre.root;

import std.string;
import dogre.renderwindow;
import dogre.rendersystem;
import dogre.scenemanager;
import dogre.framelistener;
import dogre.internals.event;
import dogre.logmanager;
import dogre.log;

extern(C)
{
    void* getRoot(const(char)* pluginFileName,const(char)* configFileName,const(char)* logFileName);
    void freeRoot(void* ptr);
    bool call_showConfigDialog(void* ptr);
    void call_saveConfig(void* ptr);
    bool call_restoreConfig(void* ptr);
    void* call_initialise(void* ptr, bool autoCreateWindow, const(char)* windowTitle, const(char)* customCapabilitiesConfig);
    void* call_getAutoCreatedWindow(void* ptr);
    void call_startRendering(void* ptr);
    void* call_createSceneManager(void* ptr, SceneTypeMask typeMask, const(char)* instanceName);
    void call_addFrameListener(void* ptr, void* ptrToListener);
	bool call_renderOneFrame(void* ptr);
    void* call_getRenderSystem(void* ptr);
    void call_queueEndRendering(void* ptr);
}

pragma(lib, "Dogre.lib");

class Root
{
    private static void* p;
    this(string pluginFileName = "plugins.cfg", string configFileName = "ogre.cfg", string logFileName = "Ogre.log")
    {
        if(p is null)
        {
            p = getRoot(pluginFileName != "" ? toStringz(pluginFileName) : "plugins.cfg",
                        configFileName != "" ? toStringz(configFileName) : "ogre.cfg",
                        logFileName != "" ? toStringz(logFileName) : "Ogre.log");
                                          //There should be some better way to do that with mixin.
            
            call_addFrameListener(p, Event.ptrToStaticFrameListenerWrapper);
            
            void* defaultlogp = LogManager.getSingleton().getDefaultLog().p;
            call_addListener(defaultlogp, Event.ptrToStaticLogListenerWrapper);
        }else{
            throw new Exception("Multiple instances of Root are not allowed!");
        }
    }
    ~this()
    {
        freeRoot(p);
		clear(p);
    }
    bool showConfigDialog()
    {
        return call_showConfigDialog(p);
    }
    void saveConfig()
    {
        call_saveConfig(p);
    }
    bool restoreConfig()
    {
        return call_restoreConfig(p);
    }
    RenderWindow initialise(bool autoCreateWindow, string windowTitle = "OGRE Render Window", string customCapabilitiesConfig = "")
    {
        return new RenderWindow(call_initialise(p, autoCreateWindow, toStringz(windowTitle), toStringz(customCapabilitiesConfig)));
    }
    RenderWindow getAutoCreatedWindow()
    {
        return new RenderWindow(call_getAutoCreatedWindow(p));
    }
    void startRendering()
    {
        call_startRendering(p);
    }
    SceneManager createSceneManager(SceneTypeMask typeMask, string instanceName = "")
    {
        return new SceneManager(call_createSceneManager(p, typeMask, toStringz(instanceName)));
    }
    void addFrameListener(FrameListener lsnr)
    {
        call_addFrameListener(p, lsnr.ptrToWrapper);
    }
	bool renderOneFrame()
	{
		return call_renderOneFrame(p);
	}
    RenderSystem getRenderSystem()
    {
        return new RenderSystem(call_getRenderSystem(p));
    }
    void queueEndRendering()
    {
        call_queueEndRendering(p);
    }
}
